package net.muchine.core.dao;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;

public abstract class GenericDaoImpl<T, K> implements GenericDao<T, K> {
	@Autowired 
	protected SqlSession sqlSession;
	protected String sqlNamespace;
	
	private Class<T> type;
		
	@SuppressWarnings("unchecked")
	public GenericDaoImpl() {
		/*
		 * if the object is not a direct child of GenericDaoImpl class, the error occurs when casting to ParameterizedType. 
		 */
		if (!this.getClass().getSuperclass().isAssignableFrom(GenericDaoImpl.class)) return;
		
		Type t = this.getClass().getGenericSuperclass();
		ParameterizedType pt = (ParameterizedType) t;
		type = (Class<T>) pt.getActualTypeArguments()[0];
		
		sqlNamespace = "net.muchine.mapper." + type.getSimpleName().toLowerCase();	
	}
	
	public void setSqlSession(SqlSession sqlSession) {
		this.sqlSession = sqlSession;
	}
	
	public long countAll() {
		return sqlSession.selectOne(sqlNamespace + ".countAll");
	}
	
	public int create(T entity) {
		return sqlSession.insert(sqlNamespace + ".create", entity);
	}

	public int update(T entity) {
		return sqlSession.update(sqlNamespace + ".update", entity);
	}

	public int delete(K key) {
		return sqlSession.delete(sqlNamespace + ".delete", key);
	}

	public T find(K key) {
		return sqlSession.selectOne(sqlNamespace + ".find", key);
	}
}
